package com.example.coolweather;

import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;

import androidx.activity.EdgeToEdge;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.GravityCompat;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.drawerlayout.widget.DrawerLayout;

import com.bumptech.glide.Glide;
import com.example.coolweather.gson.Forecast;
import com.example.coolweather.gson.Now;
import com.example.coolweather.gson.Weather;
import com.example.coolweather.service.AutoUpdateService;
import com.example.coolweather.util.HttpUtil;
import com.example.coolweather.util.SharedUtil;
import com.example.coolweather.util.ToastUtil;
import com.qweather.sdk.Callback;
import com.qweather.sdk.JWTGenerator;
import com.qweather.sdk.QWeather;
import com.qweather.sdk.basic.Indices;
import com.qweather.sdk.basic.Lang;
import com.qweather.sdk.basic.Range;
import com.qweather.sdk.basic.Unit;
import com.qweather.sdk.parameter.air.AirV1Parameter;
import com.qweather.sdk.parameter.geo.GeoCityLookupParameter;
import com.qweather.sdk.parameter.indices.IndicesParameter;
import com.qweather.sdk.parameter.weather.WeatherParameter;
import com.qweather.sdk.response.air.v1.AirIndex;
import com.qweather.sdk.response.air.v1.AirV1CurrentResponse;
import com.qweather.sdk.response.error.ErrorResponse;
import com.qweather.sdk.response.geo.GeoCityLookupResponse;
import com.qweather.sdk.response.geo.Location;
import com.qweather.sdk.response.indices.IndicesDaily;
import com.qweather.sdk.response.indices.IndicesDailyResponse;
import com.qweather.sdk.response.weather.WeatherDaily;
import com.qweather.sdk.response.weather.WeatherDailyResponse;
import com.qweather.sdk.response.weather.WeatherNow;
import com.qweather.sdk.response.weather.WeatherNowResponse;

import java.io.IOException;
import java.util.List;

import okhttp3.Call;
import okhttp3.Response;

public class WeatherActivity extends AppCompatActivity {

    private static final String TAG = "lch-WeatherActivity";
    private static final String HeFengHOST = "nw4y3cjrkw.re.qweatherapi.com";
    private static final String HeFengPROJECT_ID = "472GTHRNQX"; // 项目ID
    private static final String HeFengKID = "CHPN4FC4PU"; // 凭据ID
    private static final String HeFengKEY = "-----BEGIN PRIVATE KEY-----MC4CAQAwBQYDK2VwBCIEIL0g64aw9YDNoCBVJU5HGqvwSabg16jxjd0T0VuSjx3a-----END PRIVATE KEY-----"; // 私钥
    private ScrollView weatherLayout; // 总窗口布局
    private LinearLayout layout_forecast; // 天气预测布局
    private TextView tv_title_city; // 城市标题
    private TextView tv_title_updateTime; // 更新时间
    private TextView tv_now_temp;
    private TextView tv_now_weatherInfo; // 天气信息
    private TextView tv_aqi_date; // aqi信息
    private TextView tv_aqi_name; //
    private TextView tv_suggestion_comfort;
    private TextView tv_suggestion_carWash;
    private TextView tv_suggestion_sport;
    private Weather mWeather;
    private int getAllWeatherInfo = 0; // 一共需要从和风天气获取4种消息，如果全部都获取到，就放入到缓存中
    private ImageView iv_bing_pic; // 壁纸
    public DrawerLayout drawerLayout; // 滑动菜单
    private Button navButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_weather);
        Log.d(TAG,"create WeatherActivity");

        // 部件初始化
        weatherLayout = findViewById(R.id.weather_layout);
        tv_title_city = findViewById(R.id.tv_title_city);
        tv_title_updateTime = findViewById(R.id.tv_title_updateTime);
        tv_now_temp = findViewById(R.id.tv_now_temp);
        tv_now_weatherInfo = findViewById(R.id.tv_now_weatherInfo);
        layout_forecast = findViewById(R.id.layout_forecast);
        tv_aqi_date = findViewById(R.id.tv_aqi_date);
        tv_aqi_name = findViewById(R.id.tv_aqi_name);
        tv_suggestion_comfort = findViewById(R.id.tv_suggestion_comfort);
        tv_suggestion_carWash = findViewById(R.id.tv_suggestion_carWash);
        tv_suggestion_sport = findViewById(R.id.tv_suggestion_sport);

        // 每日一图
        iv_bing_pic = findViewById(R.id.iv_bing_pic);
        String bing_pic = SharedUtil.getInstance(WeatherActivity.this).readString("bing_pic",null);
        if (bing_pic != null)
            Glide.with(this).load(bing_pic).into(iv_bing_pic);
        else
            loadBingPic();

        drawerLayout = findViewById(R.id.drawer_layout);
        navButton = findViewById(R.id.nav_button);
        navButton.setOnClickListener(v->{
            drawerLayout.openDrawer(GravityCompat.START); // 打开滑动菜单
        });

        mWeather = new Weather();
        String weatherId = getIntent().getStringExtra("weather_id");
        String cityName = getIntent().getStringExtra("city_name");
        // mWeather = MyApplication.getInstance().mWeatherMap.get(weatherId); 这里需要改成使用Share缓存，用于保存Json数据
//        if (mWeather != null) {
//            // 有缓存时直接显示天气数据
//            showAllWeatherInfo(cityName, weatherId);
//        } else {
            // 无缓存时区服务器查询天气
            Log.d(TAG,"query weather from server, city name:" + cityName);
            weatherLayout.setVisibility(View.INVISIBLE);
            requestWeather(weatherId,cityName);
        //}
    }

    public void requestWeather(final String weatherId, final String cityName) {
        showWeatherInfo(mWeather.SET_BASIC, cityName, weatherId);
        //location:查询的地区，可通过该地区ID、经纬度进行查询经纬度格式
        //location可以填城市编号，也可以填经纬度
        QWeather instance = QWeather.getInstance(this,HeFengHOST).setLogEnable(true);
        // 通过SDK提供的JWTGenerator设置令牌生成器，其实现自TokenGenerator接口
        JWTGenerator jwt = new JWTGenerator(HeFengKEY, HeFengPROJECT_ID, HeFengKID);
        instance.setTokenGenerator(jwt);
        /*
        *Lang.ZH_HANS：表示 简体中文（Chinese Simplified）
        * Unit.METRIC：表示 公制单位（Metric Units）
        * */
        WeatherParameter weatherParameter = new WeatherParameter(weatherId).lang(Lang.ZH_HANS).unit(Unit.METRIC);
        // 获取当前天气
        Log.d(TAG,"get current weather");
        QWeather.instance.weatherNow(weatherParameter, new Callback<WeatherNowResponse>() {
            @Override
            public void onSuccess(WeatherNowResponse response) {
                Log.d(TAG,"response current weather----");
                Log.d(TAG, response.toString());
                WeatherNow now = response.getNow();
                mWeather.now.weather = now.getText(); // 天气
                mWeather.now.temp = now.getTemp() + "℃"; // 温度
                mWeather.now.humidity = now.getHumidity() + "%"; // 湿度
                showWeatherInfo(mWeather.SET_NOW, cityName, weatherId);
                getAllWeatherInfo++;
            }

            @Override
            public void onFailure(ErrorResponse errorResponse) {
                Log.d(TAG, errorResponse.toString());
                ToastUtil.show(WeatherActivity.this, "获取天气信息失败:"+errorResponse.toString());
                getAllWeatherInfo = 0;
            }

            @Override
            public void onException(Throwable e) {
                e.printStackTrace();
                Log.d(TAG,"printStackTrace current weather----");
            }
        });


        // 获取城市经纬度信息
        Log.d(TAG,"get city location");
        GeoCityLookupParameter cityLookupParameter = new GeoCityLookupParameter(cityName).range(Range.CN).number(1);
        QWeather.instance.geoCityLookup(cityLookupParameter, new Callback<GeoCityLookupResponse>() {
            @Override
            public void onSuccess(GeoCityLookupResponse response) {
                Log.d(TAG, response.toString());
                Location location = response.getLocation().get(0);
                mWeather.basic.location.lat = Double.parseDouble(location.getLat());
                mWeather.basic.location.lon = Double.parseDouble(location.getLon());
            }

            @Override
            public void onFailure(ErrorResponse errorResponse) {
                Log.d(TAG, errorResponse.toString());
                ToastUtil.show(WeatherActivity.this, "获取城市经纬度信息失败:"+errorResponse.toString());
                getAllWeatherInfo = 0;
            }

            @Override
            public void onException(Throwable e) {
                e.printStackTrace();
            }
        });

        // 根据城市经纬度信息获取AQI
        Log.d(TAG,"get AQI");
        AirV1Parameter airV1Parameter = new AirV1Parameter(mWeather.basic.location.lat, mWeather.basic.location.lon);
        QWeather.instance.airCurrent(airV1Parameter, new Callback<AirV1CurrentResponse>() {
            @Override
            public void onSuccess(AirV1CurrentResponse response) {
                Log.d(TAG, response.toString());
                AirIndex airIndex = response.getIndexes().get(0);
                mWeather.aqi.aqi_date = (int)airIndex.getAqi();
                mWeather.aqi.name = airIndex.getName();
                showWeatherInfo(mWeather.SET_AQI, cityName, weatherId);
                getAllWeatherInfo++;
            }

            @Override
            public void onFailure(ErrorResponse errorResponse) {
                Log.d(TAG, errorResponse.toString());
                ToastUtil.show(WeatherActivity.this, "获取AQI信息失败:"+errorResponse.toString());
                getAllWeatherInfo = 0;
            }

            @Override
            public void onException(Throwable e) {
                e.printStackTrace();
            }
        });

        // 获取天气预报信息
        Log.d(TAG,"get forecast weather");
        QWeather.instance.weather7d(weatherParameter, new Callback<WeatherDailyResponse>() {
            @Override
            public void onSuccess(WeatherDailyResponse response) {
                Log.d(TAG,"response forecast weather----");
                Log.d(TAG, response.toString());
                List<WeatherDaily> list =  response.getDaily();
                mWeather.basic.updateTime = response.getUpdateTime();
                for (WeatherDaily daily : list) {
                    Forecast info = new Forecast();
                    info.fxDate = daily.getFxDate();
                    info.tempMax = daily.getTempMax();
                    info.tempMin = daily.getTempMin();
                    info.textDay = daily.getTextDay();
                    mWeather.forecastList.add(info);
                }
                showWeatherInfo(mWeather.SET_FORECAST, cityName, weatherId);
                getAllWeatherInfo++;
            }

            @Override
            public void onFailure(ErrorResponse errorResponse) {
                Log.d(TAG, errorResponse.toString());
                ToastUtil.show(WeatherActivity.this, "获取天气预报信息失败:"+errorResponse.toString());
                getAllWeatherInfo = 0;
            }

            @Override
            public void onException(Throwable e) {
                e.printStackTrace();
                Log.d(TAG,"printStackTrace forecast weather----");
            }
        });

        // 获取天气指数信息
        Log.d(TAG,"get suggestion weather");
        IndicesParameter indicesParameter = new IndicesParameter(weatherId,Indices.SPT,Indices.COMF,Indices.CW);
        QWeather.instance.indices1d(indicesParameter, new Callback<IndicesDailyResponse>() {
            @Override
            public void onSuccess(IndicesDailyResponse response) {
                Log.d(TAG, response.toString());
                List<IndicesDaily> list = response.getDaily();
                for (IndicesDaily daily : list) {
                    String info = daily.getText();
                    String typeID = daily.getType();
                    if (info != null) {
                        if (typeID.equals(mWeather.suggestion.sport.typeID))
                            mWeather.suggestion.sport.info = "运动建议" + info;
                        else if (typeID.equals(mWeather.suggestion.carWash.typeID))
                            mWeather.suggestion.carWash.info = "洗车指数" + info;
                        else if (typeID.equals(mWeather.suggestion.comfort.typeID))
                            mWeather.suggestion.comfort.info = "舒适度" + info;
                    }
                }
                showWeatherInfo(mWeather.SET_SUGGESTION, cityName, weatherId);
                getAllWeatherInfo++;
            }

            @Override
            public void onFailure(ErrorResponse errorResponse) {
                Log.d(TAG, errorResponse.toString());
                ToastUtil.show(WeatherActivity.this, "获取天气指数信息失败:"+errorResponse.toString());
                getAllWeatherInfo = 0;
            }

            @Override
            public void onException(Throwable e) {
                e.printStackTrace();
            }
        });
    }

    // 根据selectSetInfo设置布局信息
    private void showWeatherInfo(final int selectSetInfo,final String cityName,final String weatherId) {
        Log.d(TAG,"showWeatherInfo:" + selectSetInfo);
        if (selectSetInfo == mWeather.SET_BASIC) {
            tv_title_city.setText(cityName);
        } else if (selectSetInfo == mWeather.SET_NOW) {
            tv_now_temp.setText(mWeather.now.temp);
            tv_now_weatherInfo.setText(mWeather.now.weather);
        } else if (selectSetInfo == mWeather.SET_AQI) {
            tv_aqi_date.setText(mWeather.aqi.aqi_date);
            tv_aqi_name.setText(mWeather.aqi.name);
        } else if (selectSetInfo == mWeather.SET_SUGGESTION) {
            tv_suggestion_sport.setText(mWeather.suggestion.sport.info);
            tv_suggestion_carWash.setText(mWeather.suggestion.carWash.info);
            tv_suggestion_comfort.setText(mWeather.suggestion.comfort.info);
        } else if (selectSetInfo == mWeather.SET_FORECAST) {
            for (Forecast forecast : mWeather.forecastList) {
                View view = LayoutInflater.from(this).inflate(R.layout.weather_forecast_item,layout_forecast,false);
                TextView tv_forecast_date = view.findViewById(R.id.tv_forecast_date);
                TextView tv_forecast_info = view.findViewById(R.id.tv_forecast_info);
                TextView tv_forecast_maxTemp = view.findViewById(R.id.tv_forecast_maxTemp);
                TextView tv_forecast_minTemp = view.findViewById(R.id.tv_forecast_minTemp);
                tv_forecast_date.setText(forecast.textDay);
                tv_forecast_info.setText(forecast.fxDate);
                tv_forecast_maxTemp.setText(forecast.tempMax);
                tv_forecast_minTemp.setText(forecast.tempMin);
                layout_forecast.addView(view);
            }
            tv_title_updateTime.setText(mWeather.basic.updateTime);
        }
        weatherLayout.setVisibility(View.VISIBLE);
        // 如果获取到当前城市的所有天气信息就保存到Map中去
        if (getAllWeatherInfo == 4) {
            getAllWeatherInfo = 0;
            mWeather.getCurrentCityAllWeatherInfo = true;
            MyApplication.getInstance().mWeatherMap.put(weatherId,mWeather);
        }
    }

    // 设置所有布局信息
    private void showAllWeatherInfo(final String cityName, final String weatherId) {
        showWeatherInfo(mWeather.SET_BASIC, cityName, weatherId);
        showWeatherInfo(mWeather.SET_NOW, cityName, weatherId);
        showWeatherInfo(mWeather.SET_AQI, cityName, weatherId);
        showWeatherInfo(mWeather.SET_FORECAST, cityName, weatherId);
        showWeatherInfo(mWeather.SET_SUGGESTION, cityName, weatherId);

        Intent intent = new Intent(WeatherActivity.this, AutoUpdateService.class);
        startService(intent);
    }

    // 加载bing每日一图
    private void loadBingPic() {
        String url = "https://bing.img.run/rand_m.php";
        HttpUtil.sendOkHttpRequest(url, new okhttp3.Callback() {
            @Override
            public void onFailure(@NonNull Call call, @NonNull IOException e) {
                e.printStackTrace();
                ToastUtil.show(WeatherActivity.this, "load bing picture failed");
            }

            @Override
            public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
                final String bing_pic = response.body().string();
                SharedUtil.getInstance(WeatherActivity.this).writeString("bing_pic", bing_pic);
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Glide.with(WeatherActivity.this).load(bing_pic).into(iv_bing_pic);
                    }
                });
            }
        });
    }

}

